package com.jwd.avmanager.parse;

import com.alibaba.fastjson.JSON;
import com.jwd.avmanager.constant.Cmd;
import com.jwd.avmanager.entity.WebSocketInfo;
import com.jwd.avmanager.server.ClientManager;
import com.jwd.avmanager.util.DebugLogger;
import com.jwd.avmanager.util.ResponseSendUtil;
import io.netty.channel.ChannelHandlerContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CopyOnWriteArrayList;

public class ParserSend {
    private static final Logger logger = LoggerFactory.getLogger(ParserSend.class);

    /**
     * 通用文件发送方法
     * @param devId 设备ID
     * @param devFileMatching 文件匹配列表
     * @param targetType 目标类型(WS-指定用户, TCP-设备关联所有用户)
     * @param targetContext 目标上下文(WS时为指定用户的ChannelHandlerContext)
     */
    public static void sendFileList(int devId,
                                    String uLoginName,
                                    CopyOnWriteArrayList<String> devFileMatching,
                                    SendTargetType targetType,
                                    ChannelHandlerContext targetContext) {
        if (devFileMatching == null || devFileMatching.isEmpty()) {
            DebugLogger.debug(logger, devId+"<--devId 设备[{}]无文件可发送"+ devId);
            return;
        }

        try {
            switch (targetType) {
                case SPECIFIC_USER:
                    sendToSpecificUser(devId,uLoginName, devFileMatching, targetContext);
                    break;
                case ALL_DEVICE_USERS:
                    sendToAllDeviceUsers(devId, devFileMatching);
                    break;
                default:
                    DebugLogger.err(logger, devId+"<--devId 未知的目标类型: {}"+ targetType);
            }
        } catch (Exception e) {
            DebugLogger.err(logger, devId+"<--devId发送文件列表异常: {}"+ e.getMessage());
        }
    }

    // 发送给特定用户
    private static void sendToSpecificUser(int devId,
                                           String uLoginName,
                                           CopyOnWriteArrayList<String> devFileMatching,
                                           ChannelHandlerContext ctx) {


        WebSocketInfo webSocketInfo = ClientManager.getInstance().getWebSocketInfo(uLoginName);
        if (webSocketInfo == null) {
            DebugLogger.err(logger, devId+"<--devId 用户[{}]的WebSocket信息不存在:"+ uLoginName);
            return;
        }

        synchronized (webSocketInfo.getAccount().intern()) {
            int start = webSocketInfo.getFileSize();
            int batchSize = Cmd.FILE_COUNT;

            for (int i = start; i < devFileMatching.size(); i += batchSize) {
                int end = Math.min(i + batchSize, devFileMatching.size());
                String message = buildFileMessage(devId, devFileMatching, i, end);

                ResponseSendUtil.writeAndFlushWs(message, ctx);
                webSocketInfo.setFileSize(end);

                try {
                    Thread.sleep(10); // 控制发送速率
                } catch (InterruptedException ignored) {}
            }

            ClientManager.getInstance().updateWebSocketInfo(webSocketInfo.getAccount(), webSocketInfo);
        }
    }

    // 发送给设备关联的所有用户
    private static void sendToAllDeviceUsers(int devId,
                                             CopyOnWriteArrayList<String> devFileMatching) {
        List<WebSocketInfo> connections = ClientManager.getInstance()
                .getWebSocketInfoByFileDevId(String.valueOf(devId));

        if (connections == null || connections.isEmpty()) {
            DebugLogger.debug(logger, devId+"<--devId  设备[{}]无关联用户连接："+ devId);
            return;
        }

        connections.parallelStream().forEach(webSocketInfo -> {
            String account = webSocketInfo.getAccount();
            if (account == null || account.isEmpty()) {
                DebugLogger.debug(logger, devId+"<--devId  跳过空账户连接");
                return;
            }

            synchronized (account.intern()) {
                ChannelHandlerContext socketClient = ClientManager.getInstance()
                        .getWebSocket(account);

                if (socketClient == null) {
                    DebugLogger.err(logger, devId+"<--devId 用户[{}]的连接已失效："+ account);
                    return;
                }

                int start = webSocketInfo.getFileSize();
                int end = Math.min(start + Cmd.FILE_COUNT, devFileMatching.size());
                String message = buildFileMessage(devId, devFileMatching, start, end);

                ResponseSendUtil.writeAndFlushWs(message, socketClient);
                webSocketInfo.setFileSize(end);
                ClientManager.getInstance().updateWebSocketInfo(account, webSocketInfo);
            }
        });
    }

    // 构建文件消息
    private static String buildFileMessage(int devId,
                                           List<String> files,
                                           int start,
                                           int end) {
        String fileNames = String.join("|", files.subList(start, end));

        Map<String, Object> payload = new HashMap<>();
        payload.put("files", fileNames);

        return String.format("{\"devID\":\"%d\",\"cmd\":\"%s\",\"value\":%s}",
                devId,
                Cmd.CMD_OUT_WEB_SOCKET_FILE_LIST,
                JSON.toJSONString(payload));
    }

    // 目标类型枚举
    public enum SendTargetType {
        SPECIFIC_USER,    // 发送给特定用户
        ALL_DEVICE_USERS  // 发送给设备关联的所有用户
    }
}